/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package continuity;

import continuity.View.GameView;
import continuity.View.MapView;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author FornetTeam
 */
public class Game implements Communication {
    /**
     * Az aktuális terület, amin a játék folyik
     */
    private volatile Map map;
    /**
     * A pálya sorszáma, amin éppen zajlik a játék.
     */
    private int level;
    /**
     * A játék karaktereit tároló lista.
     */
    private ArrayList<Character> characters;
    
    /**
     * A játék megjelenítő osztályra vonatkozó attribútum. Ezt kell értesíteni
     * a különböző modellbeli változások esetén a publikus metódusain keresztül
     * (move, fall, swap stb.).
     */
    private GameView gameView;
    
    public Game(){
        characters = new ArrayList<Character>(2);
        map = null;
    }
    
    /**
     * Inicializálja a megfelelő pályát.
     * @param level A pálya, amit inicializál. -1 esetén a következő pályát.
     * @throws FileNotFoundException Ha a pályát tartalmazó fájl nem létezik,
     * akkor FileNotFoundException-t dobunk.
     * @throws IllegalArgumentException Ha -1-nél kisebb a level értéke, akkor
     * IllegalArgumentException-t dobunk.
     */
    public void initGame(int level) {
        if (level > -1){
            this.level = level;
        } else if (level == -1) {
            this.level++;
        } else {
            throw new IllegalArgumentException("The value of level can not be less then -1.");
        }

        characters.add(0, new Character(0));
        characters.add(1, new Character(1));
        try{
            map=new Map(this,characters,Controller.levels.get(level));
        } catch (FileNotFoundException ex){
            System.out.println("FileNotFound");
            System.exit(-1);
        } catch (IOException ex){
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(-1);
        }

        //Grafikus változatnál bekerült rész
        MapView mv=map.createMapView();
        gameView=new GameView(mv);
        Controller.setGameView(gameView);
    }
    
    /**
     * A megfelelő Character újjáéledési helyát állítja be.
     * @param reloadPosition Az újjáéledés helye.
     * @param characterNumber A karakter sorszáma.
     */
    @Override
    public void setReloadPosition(Node reloadPosition, int characterNumber) {
        characters.get(characterNumber).setReloadPosition(reloadPosition);
    }
    /**
     * A pálya véget érése esetén meghívódó függvény,
     * amely felszabadítja a pályát.
     */
    @Override
    public void disposeGame(){
        map = null;
        if (Controller.levels.size() > level+1){
            nextLevel();
            gameView.refresh();
        } else {
           Controller.setGameView(null);
           gameView.endGame();
        }
    }
    
    /**
     * A paraméterként kapott sorszámú karakter újjáélesztése.
     * @param characterNumber A karakter sorszáma. 
     */
    @Override
    public void reloadCharacter(int characterNumber) {
       characters.get(characterNumber).reloadCharacter();
       gameView.refresh();
    }

    public void nextLevel(){
        if(level!=Controller.levels.size()-1) {
            initGame(level+1);
        }
    }
    
    /**
     * A megfelelő sorszámú karakter elmozdul a paraméterként kapott irányba.
     * @param characterNumber A karakter sorszáma.
     * @param dir A mozgás iránya.
     * @return Igaz, ha sikeres a mozgás.
     */
    public boolean move(final int characterNumber, final Direction dir){
        boolean success = characters.get(characterNumber).move(dir);
        return success;
    }
    
    /**
     * A megfelelő sorszámú karakter esik.
     * @param characterNumber A karakter sorszáma.
     * @return Az elmozdulás iránya.
     */
    public Direction fall(final int characterNumber){
        Direction ret=characters.get(characterNumber).fall();
        return ret;
    }
    
    /**
     * A megfelelő sorszámú karakter ugrik.
     * @param characterNumber A karakter sorszáma.
     */
    public void jump(int characterNumber){
        characters.get(characterNumber).jump();
    }

    /**
     * Az üres Room-ot elmozdítja a megfelelő irányba.
     * @param dir A mozgatás iránya.
     */
    public void swap(Direction dir) {
        boolean ret=map.swap(dir);
        if(ret==true) {
            gameView.swap(dir);
        }
    }
    
    /**
     * Ha van éppen futó játék, akkor a pályát adja vissza, ha nincs, akkor
     * a "" Stringet.
     * @return A fentebb leírt visszatérési érték.
     */
    @Override
    public String toString(){
        String ret = "";
        if (map != null){
            ret = map.toString();
        }
        return ret;
    }
    
    public void restartLevel() {
        initGame(level);
    }
}
